import * as THREE from 'three';
// 导入 轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { gsap } from 'gsap';
import * as dat from 'dat.gui'
import shaderVertex from '../shader/point/vertex.glsl'
import shaderFragment from '../shader/point/fragment.glsl'
import circlePng from '../assets/img/circle_05.png'

/**
 *  目标：粒子效果
 */



// 创建场景
const scene = new THREE.Scene();

// 创建相机 fov（角度）, aspect （宽高比）, near 近裁剪面，far 远裁剪面
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

camera.position.set(0, 5, 5)

scene.add(camera);

const texture = new THREE.TextureLoader().load(circlePng)
// 设置 point
// const particlesGeometry = new THREE.BufferGeometry()
// const positions = new Float32Array([0,0,0]);
// particlesGeometry.setAttribute("position",new THREE.BufferAttribute(positions,3));


// const shaderMaterial = new THREE.ShaderMaterial({
//     vertexShader:shaderVertex,
//     fragmentShader:shaderFragment,
//     transparent:true,
//     depthWrite:true,
//     blending:THREE.AdditiveBlending,
//     uniforms:{
//         uTexture:{value:texture}
//     }
// })

// const pointMesh = new THREE.Points(particlesGeometry,shaderMaterial)
// scene.add(pointMesh)

// 添加物体
const galaxyParams = {
    count: 5000,
    size: 60,
    radius: 5,
    branch:8,
    rotateScale: 0.2,
    color: '#ffffff',
    outerColor:'#ff0000'
}
let geometry = null
let material = null
const generateGalaxy = () => {
    // 生成顶点
    geometry = new THREE.BufferGeometry()
    // 随机生成位置
    const positions = new Float32Array(galaxyParams.count * 3)
    // 随机生成颜色
    const colors = new Float32Array(galaxyParams.count * 3)
    const color = new THREE.Color(galaxyParams.color)

    for (let i = 0, max = galaxyParams.count; i < max; i++) {
        // 分支角度
        const branchAngel = (i % galaxyParams.branch) * ((2 * Math.PI) / galaxyParams.branch)
        // 当前点距离圆心的距离
        const pointDistance = Math.random() * galaxyParams.radius * Math.pow(Math.random(), 3)

        const randomX = Math.pow(Math.random() * 2 - 1, 3) * (galaxyParams.radius - pointDistance)/5;
        const randomY = Math.pow(Math.random() * 2 - 1, 3) * (galaxyParams.radius - pointDistance)/5;
        const randomZ = Math.pow(Math.random() * 2 - 1, 3) * (galaxyParams.radius - pointDistance)/5;

        const current = i * 3;
        // x 
        positions[current] = Math.cos(branchAngel + pointDistance * galaxyParams.rotateScale) * pointDistance + randomX;
        // y
        positions[current + 1] = 0 + randomY;
        // z
        positions[current + 2] = Math.sin(branchAngel + pointDistance * galaxyParams.rotateScale) * pointDistance + randomZ;

        // 设置颜色过渡
        const mixColor = color.clone();
        mixColor.lerp(new THREE.Color(galaxyParams.outerColor), pointDistance/galaxyParams.radius)
        colors[current] = mixColor.r
        colors[current + 1] = mixColor.g
        colors[current + 2] = mixColor.b

    }
    console.info(colors)

    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
    geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))
    material = new THREE.ShaderMaterial({
        vertexShader:shaderVertex,
        fragmentShader:shaderFragment,
        transparent:true,
        depthWrite:false,
        blending:THREE.AdditiveBlending,
        vertexColors:true,

        uniforms:{
            uTexture:{value:texture},
            uPointSize :{value:galaxyParams.size},
            uColor:{value:new THREE.Color(colors)},
            uTime:{value:0},
            // uColor:{value:new THREE.color(galaxyParams.color)}
        }
    })
}
generateGalaxy()
const points = new THREE.Points(geometry, material)
scene.add(points)



// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);



// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);


// 将 webgl 渲染的 canvas 添加到 body 中
document.body.appendChild(renderer.domElement);

// 设置相机 和 场景 通过渲染器渲染
// renderer.render(scene,camera)

// 创建轨道控制器 (相机,用于渲染的dom)
const controls = new OrbitControls(camera, renderer.domElement);

renderer.shadowMap.enabled = true;


// 开启阻尼
controls.enableDamping = true;

// 添加坐标辅助器
const axesHelper = new THREE.AxesHelper(3);
scene.add(axesHelper);

// 设置 clock
const clock = new THREE.Clock();


/**
 * 渲染函数
 * L = V*T   距离 = 速度 * 时间
 */
function render() {
    material.uniforms.uTime.value = clock.getElapsedTime();

    controls.update()
    renderer.render(scene, camera)

    // 浏览器自带的 请求动画帧的方法 ，这里设置 没一帧都调用一下 render 函数
    requestAnimationFrame(render)
}
render();

// 监听窗口大小变化
window.addEventListener('resize', onWindowResize, false);

function onWindowResize() {
    // 重新设置相机的宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 重新设置相机的裁剪面(投影矩阵)
    camera.updateProjectionMatrix();

    // 更新渲染器
    renderer.setSize(window.innerWidth, window.innerHeight);
    // 设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio);
}
